// wifi_manager.c
#include "wifi_manager.h"
#include <string.h>

#define AP_CONFIG_ESP_WIFI_SSID      "beixiang"
#define AP_CONFIG_ESP_WIFI_PASS      ""
#define AP_CONFIG_ESP_WIFI_CHANNEL   6
#define AP_CONFIG_MAX_STA_CONN       4


#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static EventGroupHandle_t wifi_event_group;
static int retry_count = 0;
static const int max_retry = 5;

#define TAG "WiFiManage"
#define CONFIG_HTML_PAGE \
    "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>设备网络配置</title>" \
    "<style>*{box-sizing:border-box;margin:0;padding:0;}body{font-family:'Helvetica Neue',sans-serif;background:#f2f3f5;height:100vh;display:flex;justify-content:center;align-items:center;}" \
    ".card{background:#fff;padding:30px;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,0.1);width:320px;}h2{margin-bottom:20px;font-weight:normal;font-size:20px;color:#333;text-align:center;}" \
    "input{width:100%;padding:10px;margin-top:6px;margin-bottom:16px;border:1px solid #dcdfe6;border-radius:4px;font-size:14px;transition:border-color .2s;}" \
    "input:focus{border-color:#409eff;outline:none;}input[type=\"submit\"]{background-color:#409eff;color:white;border:none;font-size:15px;cursor:pointer;transition:background-color .2s;}" \
    "input[type=\"submit\"]:hover{background-color:#66b1ff;}</style></head><body><div class=\"card\">" \
    "<h2>设备网络配置</h2><form action=\"/submit\" method=\"POST\">" \
    "<label>WiFi SSID</label><input type=\"text\" name=\"ssid\" required>" \
    "<label>WiFi 密码</label><input type=\"password\" name=\"password\">" \
    "<label>云平台地址:mqtt://</label><input type=\"text\" name=\"tb_host\" required>" \
    "<label>设备 Token</label><input type=\"text\" name=\"tb_token\" required>" \
    "<input type=\"submit\" value=\"保存并重启\"></form></div></body></html>"

static WifiManager manager;

char* get_mqtt_token(){
    return  manager.tb_token;
}

char* get_mqtt_uri(){
    static char uri[128];  // 注意：返回 static 内存，避免返回栈变量
    snprintf(uri, sizeof(uri), "mqtt://%s", manager.tb_host);
    return uri;
}

static esp_err_t submit_post_handler(httpd_req_t *req) {
    char content[256] = {0};
    httpd_req_recv(req, content, req->content_len);
    sscanf(content, "ssid=%63[^&]&password=%63[^&]&tb_host=%63[^&]&tb_token=%127s",
           manager.wifi_ssid, manager.wifi_pass, manager.tb_host, manager.tb_token);

    nvs_handle_t nvs;
    if (nvs_open("storage", NVS_READWRITE, &nvs) == ESP_OK) {
        nvs_set_str(nvs, "ssid", manager.wifi_ssid);
        nvs_set_str(nvs, "pass", manager.wifi_pass);
        nvs_set_str(nvs, "host", manager.tb_host);
        nvs_set_str(nvs, "token", manager.tb_token);
        nvs_commit(nvs);
        nvs_close(nvs);
    }

    httpd_resp_set_type(req, "text/plain");
    httpd_resp_sendstr(req, "Config saved. Rebooting...");
    vTaskDelay(pdMS_TO_TICKS(1000));
    esp_restart();
    return ESP_OK;
}

static esp_err_t config_get_handler(httpd_req_t *req) {
    httpd_resp_set_type(req, "text/html");
    httpd_resp_send(req, CONFIG_HTML_PAGE, HTTPD_RESP_USE_STRLEN);
    return ESP_OK;
}


static void wifi_event_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id,void* event_data){
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI(TAG, "station  %s join, AID=%d",event->mac, event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI(TAG, "station %s leave, AID=%d",event->mac, event->aid);
    }else if (event_id == WIFI_EVENT_STA_CONNECTED)
    {
        wifi_event_sta_connected_t* event = (wifi_event_sta_connected_t*) event_data;
        ESP_LOGI(TAG, "sta_connected %s leave, AID=%d",event->ssid, event->aid);
    }else if (event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        wifi_event_sta_disconnected_t* event = (wifi_event_sta_disconnected_t*) event_data;
        ESP_LOGI(TAG, "sta_disconnected %s leave, AID=%d",event->ssid, event->reason);
        if (retry_count < max_retry) {
            esp_wifi_connect();
            retry_count++;
            ESP_LOGI("WIFI", "Retrying to connect to the AP...");
        } else {
            //xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT);
            ESP_LOGI("WIFI", "Failed to connect to the AP");
        }
    }
}


void launch_wifi_ap_with_web_config(void) {
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());  // 清除NVS并重新初始化
        ESP_ERROR_CHECK(nvs_flash_init());
    }

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_ap();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
        ESP_EVENT_ANY_ID,
        &wifi_event_handler,
        NULL,
        NULL));

    wifi_config_t ap_config = {
        .ap = {
            .ssid = AP_CONFIG_ESP_WIFI_SSID,
            .ssid_len = strlen(AP_CONFIG_ESP_WIFI_SSID),
            .password = AP_CONFIG_ESP_WIFI_PASS,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK,
            .max_connection = AP_CONFIG_MAX_STA_CONN,
            .channel = AP_CONFIG_ESP_WIFI_CHANNEL
        }
    };
    if (strlen(AP_CONFIG_ESP_WIFI_PASS) == 0) {
        ap_config.ap.authmode = WIFI_AUTH_OPEN;
    }
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP,&ap_config));
    ESP_ERROR_CHECK(esp_wifi_start());
    ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",AP_CONFIG_ESP_WIFI_SSID,AP_CONFIG_ESP_WIFI_PASS,AP_CONFIG_ESP_WIFI_CHANNEL);

    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    httpd_start(&manager.server, &config);

    httpd_uri_t uri_get = {
        .uri = "/",
        .method = HTTP_GET,
        .handler = config_get_handler
    };

    httpd_uri_t uri_post = {
        .uri = "/submit",
        .method = HTTP_POST,
        .handler = submit_post_handler
    };

    httpd_register_uri_handler(manager.server, &uri_get);
    httpd_register_uri_handler(manager.server, &uri_post);
}

void wifi_manager_init() {
    manager.in_config_mode = false;
    manager.rpc_method_count = 0;
    memset(manager.wifi_ssid, 0, sizeof(manager.wifi_ssid));
    memset(manager.wifi_pass, 0, sizeof(manager.wifi_pass));
    memset(manager.tb_host, 0, sizeof(manager.tb_host));
    memset(manager.tb_token, 0, sizeof(manager.tb_token));
    manager.tb_port = 1883;
}

static void load_config_from_nvs(void) {
    nvs_handle_t nvs;
    size_t len;
    if (nvs_open("storage", NVS_READONLY, &nvs) == ESP_OK) {
        len = sizeof(manager.wifi_ssid); nvs_get_str(nvs, "ssid", manager.wifi_ssid, &len);
        len = sizeof(manager.wifi_pass); nvs_get_str(nvs, "pass", manager.wifi_pass, &len);
        len = sizeof(manager.tb_host);   nvs_get_str(nvs, "host", manager.tb_host, &len);
        len = sizeof(manager.tb_token);  nvs_get_str(nvs, "token", manager.tb_token, &len);
        nvs_close(nvs);
    }
}


static void connect_to_wifi(void) {
    ESP_ERROR_CHECK(esp_netif_init());
    esp_event_loop_create_default();
    esp_netif_t *sta_netif =  esp_netif_create_default_wifi_sta();
    esp_netif_set_hostname(sta_netif,"BeixiangGateway");

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    wifi_config_t wifi_config = {};
    strncpy((char*)wifi_config.sta.ssid, manager.wifi_ssid, sizeof(wifi_config.sta.ssid));
    strncpy((char*)wifi_config.sta.password, manager.wifi_pass, sizeof(wifi_config.sta.password));


    esp_wifi_set_mode(WIFI_MODE_STA);
    esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
    esp_wifi_start();

    ESP_LOGI(TAG, "connection WiFi: %s", manager.wifi_ssid);
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
       ESP_EVENT_ANY_ID,
       &wifi_event_handler,
       NULL,
       NULL));

    ESP_ERROR_CHECK(esp_wifi_connect());
}

void wifi_manager_begin(void) {
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());  // 清除NVS并重新初始化
        ESP_ERROR_CHECK(nvs_flash_init());
    }
    // 加载配置略...
    load_config_from_nvs();
    // WiFi 初始化略...
    connect_to_wifi();
}
